package fuzion24.device.vulnerability.vulnerabilities.framework.media;

import android.content.Context;
import android.content.res.AssetManager;
import android.os.Build;
import android.util.Log;

import org.apache.commons.io.FilenameUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import fuzion24.device.vulnerability.util.CPUArch;
import fuzion24.device.vulnerability.vulnerabilities.VulnerabilityTest;
import fuzion24.device.vulnerability.vulnerabilities.helper.TestResult;

import static fuzion24.device.vulnerability.vulnerabilities.helper.BinaryAssets.extractAsset;
import static fuzion24.device.vulnerability.vulnerabilities.helper.BinaryAssets.extractZipAsset;
import static fuzion24.device.vulnerability.vulnerabilities.helper.CrashCheck.execute;

/**
 * Created by fuzion24 on 8/10/15.
 */

public class StageFright {

    private static final String TAG = "StageFright";

    static {
        System.loadLibrary("stagefright");
    }

    private static void exec(String executionCommand) throws Exception {
        Process p = Runtime.getRuntime().exec(executionCommand);
        p.waitFor();
    }

    public static List<VulnerabilityTest> getTests(Context context) {
        try {
            File dataDir = context.getFilesDir();


            final String stageFrightAssetPath = "stagefright/stagefright_media_files.zip";
            final String extractionDir = dataDir.getAbsolutePath() + File.separator + "stagefright_media" + File.separator;

            extractZipAsset(context, stageFrightAssetPath, extractionDir);

            File stagefrightMediaFilesFolder = new File(extractionDir);

            List<VulnerabilityTest> tests = new ArrayList<>();

            final String extractedBinaryTester = dataDir.getAbsolutePath() + File.separator + getNativeAppName();
            extractAsset(context, "stagefright" + File.separator + getNativeAppName(),
                    extractedBinaryTester);
            exec("chmod 700 " + extractedBinaryTester);

            Log.d(TAG, "Is directory: "  + stagefrightMediaFilesFolder.isDirectory());
            File[] mediaFiles = stagefrightMediaFilesFolder.listFiles();

            for (final File mediaFile : stagefrightMediaFilesFolder.listFiles()) {
                tests.add(new VulnerabilityTest() {
                    @Override
                    public String getCVEorID() {
                        return FilenameUtils.removeExtension(mediaFile.getName());
                    }

                    @Override
                    public List<CPUArch> getSupportedArchitectures() {
                        ArrayList<CPUArch> archs = new ArrayList<>();
                        archs.add(CPUArch.ARM);
                        archs.add(CPUArch.ARM7);
                        archs.add(CPUArch.ARM8);
                        return archs;
                    }

                    @Override
                    public boolean isVulnerable(Context context) throws Exception {
                        TestResult result = execute(context, 5, extractedBinaryTester, mediaFile.getAbsolutePath());
                        Log.d(TAG, "Test result: " + result.toString());
                        if (result.isOk()) {
                            return false;
                        } else if (result == TestResult.CRASH) {
                            return true;
                        } else if (result == TestResult.HANG) {
                            throw new Exception("Test is hanging");
                        } else if (result == TestResult.ERROR) {
                            throw new Exception("Test error");
                        }
                        throw new Exception("Unknown test result");
                    }
                });
            }
            return tests;
        }catch(Exception e){
            e.printStackTrace();
        }

        return new ArrayList<>();
    }

    public static String getNativeAppName() {
        return Build.VERSION.SDK_INT >= 16 ? "stagefrightCheck-pie" : "stagefrightCheck";
    }
}
